#include "ABSBondInfo.h"
#include "QBIssuerInfo.h"
#include <vector>
#include <string.h>
#include <core/Utility.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifdef	_DEBUG
//#define	new	DEBUG_NEW
#endif
namespace{
	const std::vector<std::string> g_sBaseType = { "", "Auto", "Credit Card", "CLO", "RMBS", "Consumer Loan", "Bad Assets", "Lease", "Small Business", "Railway", "Construction", "", "" };
	const std::vector<std::string> g_sTrancheClassFirst = { "A", "A1", "A-1", "A1-1", "A1-2", "A2", "A-2", "A3", "A-3", "A4", "A-4", "A5", "AA", "AAA", "SENIOR" };
	const std::vector<std::string> g_sTrancheClassSecond = { "B", "C", "D" };
	const char g_sTrancheClassSub[] =  "SUB" ;
}

CABSBondInfo::CABSBondInfo(){
	Clear();
}

CABSBondInfo::CABSBondInfo(const CABSBondInfo& one){
	Clear();
	FIELDCOPY(m_sBondKey, one.m_sBondKey);
	FIELDCOPY(m_sBaseType, one.m_sBaseType);
	FIELDCOPY(m_sTrancheClass, one.m_sTrancheClass);
	FIELDCOPY(m_sSeriesName, one.m_sSeriesName);
	FIELDCOPY(m_sIssuerCode, one.m_sIssuerCode);
}

CABSBondInfo::~CABSBondInfo(){
}

void CABSBondInfo::Clear(){
	memset(m_sBondKey, 0, sizeof(m_sBondKey));
	memset(m_sBaseType, 0, sizeof(m_sBaseType));
	memset(m_sTrancheClass, 0, sizeof(m_sTrancheClass));
	memset(m_sSeriesName, 0, sizeof(m_sSeriesName));
	memset(m_sIssuerCode, 0, sizeof(m_sIssuerCode));
}

void CABSBondInfo::SetBondKey(const char* sBondKey)
{
	memset(m_sBondKey, 0, sizeof(m_sBondKey));
	if (NULL == sBondKey) return;
	FIELDCOPY(m_sBondKey, sBondKey);
}
void CABSBondInfo::SetBaseType(const char* sBaseType, const char* sNPL)
{
	memset(m_sBaseType, 0, sizeof(m_sBaseType));
	if (NULL == sBaseType) return;

	if (strcmp(sBaseType, "Credit Card") == 0 || strcmp(sBaseType, "CreditCard") == 0)
	{
		if (strcmp(sNPL, "true") == 0)
			FIELDCOPY(m_sBaseType, "Bad Assets");
		else
			FIELDCOPY(m_sBaseType, "Credit Card");
		return;
	}
	FIELDCOPY(m_sBaseType, sBaseType);
}
void CABSBondInfo::SetTrancheClass(const char* sTrancheClass){
	memset(m_sTrancheClass, 0, sizeof(m_sTrancheClass));
	if (NULL == sTrancheClass) return;
	FIELDCOPY(m_sTrancheClass, sTrancheClass);
}
void CABSBondInfo::SetSeriesName(const char* sSeriesName){
	memset(m_sSeriesName, 0, sizeof(m_sSeriesName));
	if (NULL == sSeriesName) return;
	FIELDCOPY(m_sSeriesName, sSeriesName);
}
void CABSBondInfo::SetIssuerCode(const char* sIssuerCode){
	memset(m_sIssuerCode, 0, sizeof(m_sIssuerCode));
	if (NULL == sIssuerCode) return;
	FIELDCOPY(m_sIssuerCode, sIssuerCode);
}
const char* CABSBondInfo::GetBondKey(){
	return m_sBondKey;
}
const char* CABSBondInfo::GetBaseType()const{
	return m_sBaseType;
}
const char* CABSBondInfo::GetTrancheClass()const{
	return m_sTrancheClass;
}
const char* CABSBondInfo::GetSeriesName()const{
	return m_sSeriesName;
}
const char* CABSBondInfo::GetIssuerCode()const{
	return m_sIssuerCode;
}

bool CABSBondInfo::CheckCommon(const BLHCONDITION& Cond) const
{
	for (int i = 0; i < 10; i++)
	{
		switch (Cond.nABSCommonUse[i])
		{
		case COMMON_ALL:
			return false;
			break;
		case COMMON_CLO:
			if (CheckBaseType(g_sBaseType[BASETYPE_CLO].c_str()))return true;
			break;
		case COMMON_CONSUMER:
			if (CheckBaseType(g_sBaseType[BASETYPE_CONSUMER].c_str()))return true;
			break;
		case COMMON_RMBS:
			if (CheckBaseType(g_sBaseType[BASETYPE_RMBS].c_str()))return true;
			break;
		case COMMON_CARD:
			if (CheckBaseType(g_sBaseType[BASETYPE_CARD].c_str()))return true;
			break;
		case COMMON_AUTO:
			if (CheckBaseType(g_sBaseType[BASETYPE_AUTO].c_str()))return true;
			break;
		default:
			return false;
			break;
		}
	}
	return false;
}

bool CABSBondInfo::CheckBaseType(const BLHCONDITION& Cond) const
{
	for (int i = 0; i < 20; i++)
	{
		int nType = Cond.nABSBaseType[i];
		if (nType == BASETYPE_OTHER)
		{
			for (int n = BASETYPE_ALL + 1; n < BASETYPE_OTHER; n++)
			{
				if (CheckBaseType(g_sBaseType[n].c_str()))return false;
			}
			return true;
		}
		else if (nType > BASETYPE_ALL && nType < BASETYPE_NUM)
		{
			if (CheckBaseType(g_sBaseType[nType].c_str()))return true;
		}
		else
		{
			return false;
		}
	}
	return false;
}

bool CABSBondInfo::CheckBaseType(const char* sType) const
{
	if (!sType)return false;
	return (strcmp(m_sBaseType, sType) == 0);
}

bool CABSBondInfo::CheckTrancheClass(const BLHCONDITION& Cond) const
{
	for (int i = 0; i < 10; i++)
	{
		int nClass = Cond.nABSTrancheClass[i];
		if (nClass == TRANCHECLASS_ALL)return false;
		switch (nClass)
		{
		case TRANCHECLASS_FIRST:	//优先级
		{
			std::vector<std::string>::const_iterator it = std::find(g_sTrancheClassFirst.begin(), g_sTrancheClassFirst.end(), m_sTrancheClass);
			if (it != g_sTrancheClassFirst.end())return true;
			break;
		}
		case TRANCHECLASS_SECOND:	//次优级
		{
			std::vector<std::string>::const_iterator it = std::find(g_sTrancheClassSecond.begin(), g_sTrancheClassSecond.end(), m_sTrancheClass);
			if (it != g_sTrancheClassSecond.end())return true;
			break;
		}
		case TRANCHECLASS_SUB:		//次级
		{
			if (strcmp(g_sTrancheClassSub, m_sTrancheClass) == 0)return true;
			break;
		}
		default:
			return false;
			break;
		}
	}
	return false;
}

bool CABSBondInfo::CheckSeries(const BLHCONDITION& Cond) const
{
	CQBIssuerInfo& iinfo = CQBIssuerInfo::ABSBondSeries();
	for (int i = 0; i < 200; i++)
	{
		if (Cond.szABSSeries[i][0] == '\0')return false;
		const IssuerInfo* pI = iinfo.GetIssuerInfo(Cond.szABSSeries[i]);
		if (pI && strcmp(m_sSeriesName, pI->field((int)kIssuerInfo::Full_Name_C)) == 0)return true;
	}
	return false;
}

bool CABSBondInfo::CheckIssuer(const BLHCONDITION& Cond) const
{
	for (int i = 0; i < BLH_ISSUERCOUNT; i++)
	{
		if (Cond.szABSIssuer[i][0] == '\0')return false;
		if (strcmp(m_sIssuerCode, Cond.szABSIssuer[i]) == 0)return true;
	}
	return false;
}
